# Create your views here.
from django.template import loader, Context
from django.http import HttpResponse
from django.core import serializers
from django.utils import simplejson
from itp.wp.models import *

class DictText():
	def __init__(self, text=None, dict=None):
		self.text = text
		self.dict = dict
		pass
		# text with format of : 00:00,50;
	def textTodict(self):
		tmp = self.text.split(';')
		self.dict = {}
		for t in tmp:
			t = t.split(',')
			if len(t) > 1:
				self.dict[t[0]] = int(t[1])
		return self.dict
	def dictTotext(self):
		self.text = ''
		for d in self.dict:
			self.text += d + ',' + str(self.dict[d]) + ';'
		self.text = self.text[:-1]
		return self.text
		
class Algorithm():
	def __init__(self, type = None):
		self.type = type
		self.user_id = 0
		self.loc = []
		self.rssi_dict = {}
		
	def getStrongestMac(self):
		max_rssi = -100
		max_rssi_mac = ''
		for mac in self.rssi_dict:
			if self.rssi_dict[mac] > max_rssi:
				max_rssi = self.rssi_dict[mac]
				max_rssi_mac = mac
		#print max_rssi_mac
		return max_rssi_mac
		
	def getStrongest(self):
		aploc = APLocation.objects.get(mac_address = self.getStrongestMac())
		self.loc = [aploc.lat, aploc.long]
		return self.loc
		
	def getThreePoint(self):
		# dict rssi - distance 
		pass
	
	def getFingerPrint(self, op):
		sample_points = SamplePointLoc.objects.filter(field_id = self.field_id)
		distance_list = []
		distance_dict = {}
		
		for sp in sample_points:
			d = 0
			sample_rssi = SamplePointRssi.objects.filter(sample_point = sp)
			for sr in sample_rssi:
				if sr.mac in self.rssi_dict:
					d += ( self.rssi_dict[sr.mac] - sr.rssi ) * ( self.rssi_dict[sr.mac] - sr.rssi )
			distance_list.append(d)
			distance_dict[d] = sp.id
		#print len(distance_list)
		distance_list.sort()
		#print distance_list
		d1 = float(distance_list[0]) + 0.01
		d2 = float(distance_list[1])
		d3 = float(distance_list[2])
		d4 = float(distance_list[3])
		
		p1 = SamplePointLoc.objects.get(id = distance_dict[distance_list[0]])
		p2 = SamplePointLoc.objects.get(id = distance_dict[distance_list[1]])
		p3 = SamplePointLoc.objects.get(id = distance_dict[distance_list[2]])
		p4 = SamplePointLoc.objects.get(id = distance_dict[distance_list[3]])
		
		if op == 'a1':
			# no average
			_x = p1.x
			_y = p1.y
		elif op == 'a2':
			# get 2 average
			_x = ( p1.x + p2.x ) / 2.0
			_y = ( p1.y + p2.y ) / 2.0
		elif op == 'a3':
			# get 3 average
			_x = ( p1.x + p2.x + p3.x ) / 3.0
			_y = ( p1.y + p2.y + p3.y ) / 3.0
		elif op == 'a4':
			_x = ( p1.x + p2.x + p3.x + p4.x ) / 4.0
			_y = ( p1.y + p2.y + p3.y + p4.y ) / 4.0
		
		elif op == '_s3':
			sumd = d1 + d2 + d3
			_d1 = d3/sumd
			_d2 = d2/sumd
			_d3 = d1/sumd
			_x = p1.x * _d1 + p2.x * _d2 + p3.x * _d3
			_y = p1.y * _d1 + p2.y * _d2 + p3.y * _d3
		elif op == '_s4':
			sumd = d1 + d2 + d3 + d4
			_d1 = d4/sumd
			_d2 = d3/sumd
			_d3 = d2/sumd
			_d4 = d1/sumd
			_x = p1.x * _d1 + p2.x * _d2 + p3.x * _d3 + p4.x * _d4
			_y = p1.y * _d1 + p2.y * _d2 + p3.y * _d3 + p4.y * _d4
		
		elif op == 's3':
			sumd = 1/d1 + 1/d2 + 1/d3
			_d1 = 1/(sumd*d1)
			_d2 = 1/(sumd*d2)
			_d3 = 1/(sumd*d3)
			_x = p1.x * _d1 + p2.x * _d2 + p3.x * _d3
			_y = p1.y * _d1 + p2.y * _d2 + p3.y * _d3
		elif op == 's4':
			sumd = 1/d1 + 1/d2 + 1/d3 + 1/d4
			_d1 = 1/(sumd*d1)
			_d2 = 1/(sumd*d2)
			_d3 = 1/(sumd*d3)
			_d4 = 1/(sumd*d4)
			_x = p1.x * _d1 + p2.x * _d2 + p3.x * _d3 + p4.x * _d4
			_y = p1.y * _d1 + p2.y * _d2 + p3.y * _d3 + p4.y * _d4
			
		else:
			return []
			
		self.loc= [_x, _y]
		print op
		print self.loc
		return self.loc
	
	def getRssi(self, op):
		MacRssi = UserMacRssi.objects.filter(user_id=self.user_id).order_by('-timestamp')
		self.field_id = MacRssi[0].field_id
		rssi_text1 = MacRssi[0].mac_rssi
		rssi_text2 = MacRssi[1].mac_rssi
		rssi_text3 = MacRssi[2].mac_rssi
		rssi_dict1 = DictText(text = rssi_text1).textTodict()
		rssi_dict2 = DictText(text = rssi_text2).textTodict()
		rssi_dict3 = DictText(text = rssi_text3).textTodict()
		
		if op == 1:
			self.rssi_dict = DictText(text = MacRssi[0].mac_rssi).textTodict()
		elif op == 2:
			for r in rssi_dict1:
				if r in rssi_dict2:
					self.rssi_dict[r] = ( rssi_dict1[r] + rssi_dict2[r] ) / 2 
		elif op == 3:
			for r in rssi_dict1:	
				if r in rssi_dict2 and r in rssi_dict3:
					self.rssi_dict[r] = ( rssi_dict1[r] + rssi_dict2[r] + rssi_dict3[r]) / 3
		else:
			pass
			
	def getLocation(self):
		if self.type == 'Strongest':
			return self.getStrongestIndoor()
		elif self.type == 'ThreePoint':
			return self.getThreePoint()
		elif self.type == 'FingerPrint':
			return self.getFingerPrint()
		else:
			pass

	def updateLocation(self):
		self.getRssi(1)
		outdoor = self.getStrongest()
		try:
			ul_latest = UserLocation.objects.filter(user_id=self.user_id).latest('timestamp')
			ul_count = ul_latest.count + 1
		except:
			ul_count = 0
		try:
			session = UserSession.objects.filter(user_id=self.user_id).latest('timestamp')
			session_id = session.id
		except:
			session_id = 0
		
		algorithm_type = ['a1', 'a2', 'a3', 'a4', 's3', 's4', 'r2', 'r3', 'r4', '3p']
		
		for at in algorithm_type:		
			if at == '3p':
				#indoor = self.getFingerPrint()
				pass
			else:
				indoor = self.getFingerPrint(at)
			if indoor:
				ul = UserLocation(
								user_id = self.user_id, 
								field_id = self.field_id, 
								x = indoor[0], 
								y = indoor[1], 
								lat = outdoor[0], 
								long = outdoor[1],
								algorithm_type = at,
								session_id = session_id, 
								count = ul_count
							)
		
				ul.save()
		
class MacFilter():
	def __init__(self, field_id = None, rssi_text = None):
		try:
			self.field_id = field_id
		except:
			self.field_id = 0
		self.rssi_text = rssi_text
		self.rssi_dict = {}
		
	def run(self):
		DT = DictText(text = self.rssi_text)
		self.rssi_dict = DT.textTodict()
		#print self.rssi_dict
		self.rssi_dict_update = {}
		self.rssi_text_update = ''
		ap_in_db = APLocation.objects.filter(field_id = self.field_id)
		for ap in ap_in_db:
			if ap.mac_address in self.rssi_dict:
				self.rssi_dict_update[ap.mac_address] = self.rssi_dict[ap.mac_address]
		
		DT2 = DictText(dict = self.rssi_dict_update)
		self.rssi_text_update = DT2.dictTotext()
		print self.rssi_text_update
		
	def update(self):
		if len(self.rssi_dict_update) >= 3:
		## update user MAC-RSSI log
			umr = UserMacRssi(
								user_id = 0, 
								field_id = self.field_id, 
								mac_rssi = self.rssi_text_update
							) 
			umr.save()
		else:
			print "the scanning result < 3, positioning failed"
			self.rssi_text_update = ''
		
def MainHandler(request, field_id):
	# algorithm type : default - FingerPrint
	try:
		algorithm_type = request.GET['algorithm_type']
	except:
		algorithm_type = 's3'
	# Track : default - not shown
	try:
		if request.GET['show_track'] == '1':
			show_track = True
		else:
			show_track = False
	except:
		show_track = False
	# Sample Point : default - not shown
	try:
		if request.GET['show_sample'] == '1':
			show_sample = True
		else:
			show_sample = False
	except:
		show_sample = False
	# User Location : default - Show
	try:
		if request.GET['show_user'] == '0':
			show_user = False
		else:
			show_user = True
	except:
		show_user = True
	# AP Location : default - not show
	try:
		if request.GET['show_ap'] =='1':
			show_ap = True
	except:
		show_ap = False
	try:	
		if request.GET['fuzzy']:
			use_fuzzy = True
	except:
		use_fuzzy = False
	try:
		mt = request.GET['mt'] # magnification times
	except:
		mt = 1
	try:
		session_id = int(request.GET['session_id'])
	except:
		try:
			session_id = UserSession.objects.filter(user_id=0, field_id=field_id).latest('timestamp').id
		except:
			session_id = 0
	
	#Algorithm().updateLocation()
	
	# thirdly get the GET value to decide the following action
	# type = {'indoor'(default), 'allap', 'outdoor'}
	if True:
		type = request.GET['type']  
		# choose the type 
		if type == 'allap':
			aploc = APLocation.objects.all()
			t = loader.get_template("gmap.html")
			c = Context({
						'aploc':aploc,
						'title':"Show All Aps in SJTU",
						})
			return HttpResponse(t.render(c))
			
		elif type == 'outdoor':
			t = loader.get_template("gmap.html")
			usrloc = UserLocation.objects.filter(user_id=0, field_id=field_id).latest('timestamp')
			print usrloc.lat
			c = Context({
						'title':"The Outdoor Positioning System",
						#'aploc':aploc,
						'usrloc':usrloc,
						'field_id':field_id,
						'algorithm_type': algorithm_type,
						})
			return HttpResponse(t.render(c))
				
		elif type == 'indoor':
			t = loader.get_template("main.html") 
			c = Context({
					'title': "Show the Building: " + field_id,
					'algorithm_type': algorithm_type,
					'use_fuzzy': use_fuzzy, 
					'field_id': field_id,  # which is field_id in each table 
					'mt': mt,
					'show_sample': show_sample,
					#'show_track': show_track,
					'show_track' : True,
					'show_ap': show_ap,
					'show_user': show_user,
					'session_id': session_id,})
			return HttpResponse(t.render(c))
		else:
			pass
	#except:
		pass
	return HttpResponse("<h1>Something ERROR!</h1>")
	
def DataGenerater(request, b):
	# function : transform data in db to JSON
	response = HttpResponse()
	response['Content-Type'] = "text/javascript"
	try:
		cat = request.GET['cat']
		if cat == "bp":
			data_query = BuildingPoint.objects.filter(field_id=b)
		
		elif cat == "ap":
			data_query = APLocation.objects.filter(field_id=b)
		
		elif cat == "track":
			data_query = UserLocation.objects.filter(field_id=b)
			try:
				s = int(request.GET['session_id'])
				data_query = data_query.filter(session_id=s)
			except:
				pass
			try:
				at = request.GET['algorithm_type']
				data_query = data_query.filter(algorithm_type = at)
			except:
				pass
			data_query = data_query.order_by('-count')[:40]
			
		elif cat == "sample":
			data_query = SamplePointLoc.objects.filter(field_id=b)
		
		elif cat == "user":
			try: 
				algorithm_type = request.GET['algorithm_type']
			except:
				algorithm_type = 's3'
			data_query = UserLocation.objects.filter(user_id=0, field_id=b, algorithm_type=algorithm_type).latest('timestamp')
			location = {}
			location['x'] = data_query.x;
			location['y'] = data_query.y;
			return HttpResponse(
				simplejson.dumps(location),
				content_type = 'application/javascript; charset=utf8'
			)
	except:
		pass
	
	response.write(serializers.serialize("json", data_query))
	return response

def SessionCreator(request):
	try:
		user_id = request.GET['user_id']
		field_id = request.GET['field_id']
	except:
		user_id = 0
		field_id = 0
	
	session = UserSession(user_id = user_id, field_id = field_id)
	session.save()
	
	return HttpResponse(session.id)
	
def PostRssiHandler(request):
	if request.method == 'POST':
		## get rssi value
		rssi_text = request.POST['rssi']
		## filter mac address and get field_id(by strongest)
		filter = MacFilter(rssi_text = rssi_text, field_id = 0)
		filter.run()
		filter.update()
		# break if filter returns 0
		if not filter.rssi_text_update:
			return HttpResponse('No update!')
			
		Algorithm().updateLocation()
		
		return HttpResponse('Update SUCESSFULLY')
		#print filter.rssi_text_update
		#return HttpResponse(filter.rssi_text_update)
		
	else: # for test
		rssi_text = "74:ea:3a:60:86:f4,-78;00:0a:eb:e1:16:96,-66;1c:af:f7:a7:89:10,-48;c8:3a:35:18:62:70,-82;"
		filter = MacFilter(rssi_text = rssi_text, field_id = 0)
		filter.run()
		filter.update()
		# break if filter returns 0
		if not filter.rssi_text_update:
			return HttpResponse('No update!')
					
		Algorithm().updateLocation()
		
		return HttpResponse('Update SUCESSFULLY')